#region Apache License
/* 
   Copyright 2011 Jorge Teixeira

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;

namespace AdHoc.Wavesque.Example
{
    /// <summary>
    /// Example of use of AdHoc.Wavesque.
    /// </summary>
    public partial class Example : Form
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Example"/> class.
        /// </summary>
        public Example()
        {
            InitializeComponent();
            
            textBoxColor.BackColor = colorDialog.Color;
            numericUpDownAmplitude.Maximum = decimal.MaxValue;
            numericUpDownFrequency.Maximum = decimal.MaxValue;
            numericUpDownPhase.Maximum = decimal.MaxValue;

            InitializeGraphPane(graphSinusoid, Properties.Resources.Sinusoid, Properties.Resources.X, Properties.Resources.Y);
            InitializeGraphPane(graphSquareWave, Properties.Resources.SquareWave, Properties.Resources.X, Properties.Resources.Y);
            InitializeGraphPane(graphTriangleWave, Properties.Resources.TriangleWave, Properties.Resources.X, Properties.Resources.Y);
            InitializeGraphPane(graphSawtoothWave, Properties.Resources.SawtoothWave, Properties.Resources.X, Properties.Resources.Y);
        }

        /// <summary>
        /// Handles the Click event of the buttonColor control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void buttonColor_Click(object sender, EventArgs e)
        {
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                textBoxColor.BackColor = colorDialog.Color;
            }
        }

        /// <summary>
        /// Handles the CheckedChanged event of the checkBoxPoints control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void checkBoxPoints_CheckedChanged(object sender, EventArgs e)
        {
            numericUpDownPoints.Enabled = checkBoxPoints.Checked;
            numericUpDownPoints.Maximum = Convert.ToDecimal(uint.MaxValue);
        }

        /// <summary>
        /// Handles the Click event of the buttonDraw control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void buttonDraw_Click(object sender, EventArgs e)
        {
            try
            {
                double amplitude = Convert.ToDouble(numericUpDownAmplitude.Value);
                double frequency = Convert.ToDouble(numericUpDownFrequency.Value);
                double phase = Math.PI * Convert.ToDouble(numericUpDownPhase.Value) / 180.0;

                Sinusoidesque f1 = new Sinusoidesque(amplitude, frequency, phase);
                Squaresque f2 = new Squaresque(amplitude, frequency, phase);
                Trianglesque f3 = new Trianglesque(amplitude, frequency, phase);
                SawToothesque f4 = new SawToothesque(amplitude, frequency, phase);

                double[] x1;
                double[] y1;
                GetValues(f1, out x1, out y1);

                double[] x2;
                double[] y2;
                GetValues(f2, out x2, out y2);
                
                double[] x3;
                double[] y3;
                GetValues(f3, out x3, out y3);

                double[] x4;
                double[] y4;
                GetValues(f4, out x4, out y4);
                
                DisplayValues(graphSinusoid, x1, y1);
                DisplayValues(graphSquareWave, x2, y2);
                DisplayValues(graphTriangleWave, x3, y3);
                DisplayValues(graphSawtoothWave, x4, y4);
            }
            catch (OverflowException ex)
            {
                System.Diagnostics.Trace.TraceInformation(ex.Message);
            }
        }

        /// <summary>
        /// Initializes the graph pane of a ZedGraphControl instance.
        /// </summary>
        /// <param name="ctrl">The ZedGraphControl instance.</param>
        /// <param name="title">The title of the graph.</param>
        /// <param name="xTitle">The title of the abscissae.</param>
        /// <param name="yTitle">The title of the ordinates.</param>
        private void InitializeGraphPane(ZedGraphControl ctrl, string title, string xTitle, string yTitle)
        {
            if (ctrl == null)
                return;

            if (string.IsNullOrEmpty(title))
                title = string.Empty;

            if (string.IsNullOrEmpty(xTitle))
                xTitle = string.Empty;

            if (string.IsNullOrEmpty(yTitle))
                yTitle = string.Empty;

            GraphPane gp = ctrl.GraphPane;
            GraphPane gp2 = new GraphPane(gp.Rect, title, xTitle, yTitle);
            ctrl.GraphPane = gp2;
        }

        /// <summary>
        /// Gets the values of the waveforms.
        /// </summary>
        /// <param name="f">The waveform.</param>
        /// <param name="x">Abscissae.</param>
        /// <param name="y">Ordinates.</param>
        private void GetValues(Esque f, out double[] x, out double[] y)
        {
            if (f == null)
            {
                x = new double[] { 0.0 };
                y = new double[] { 0.0 };
                return;
            }

            if (checkBoxPoints.Checked)
            {
                uint numberPoints = Convert.ToUInt32(numericUpDownPoints.Value);

                if (radioButtonNoRectification.Checked)
                {
                    f.GetValues(numberPoints, out x, out y);
                }
                else if (radioButtonHWRectification.Checked)
                {
                    f.ToHalfWaveRectification(numberPoints, out x, out y);
                }
                else if (radioButtonFWRectification.Checked)
                {
                    f.ToFullWaveRectification(numberPoints, out x, out y);
                }
                else
                {
                    throw new ApplicationException();
                }
            }
            else
            {
                if (radioButtonNoRectification.Checked)
                {
                    f.GetValues(out x, out y);
                }
                else if (radioButtonHWRectification.Checked)
                {
                    f.ToHalfWaveRectification(out x, out y);
                }
                else if (radioButtonFWRectification.Checked)
                {
                    f.ToFullWaveRectification(out x, out y);
                }
                else
                {
                    throw new ApplicationException();
                }
            }
        }

        /// <summary>
        /// Plots the given values on the given ZedGraphControl instance.
        /// </summary>
        /// <param name="ctrl">The ZedGraphControl instance.</param>
        /// <param name="x">Abscissae.</param>
        /// <param name="y">Ordinates.</param>
        private void DisplayValues(ZedGraphControl ctrl, double[] x, double[] y)
        {
            if (ctrl == null || x == null || y == null)
                return;

            GraphPane gp = ctrl.GraphPane;
            gp.AddCurve(DateTime.Now.TimeOfDay.ToString(), x, y, textBoxColor.BackColor, SymbolType.Diamond);
            gp.AxisChange();
            ctrl.Invalidate();
        }
    }
}
